package monsterRun.client.view;

import java.awt.BorderLayout;
import java.awt.Component;
import java.io.IOException;
import java.net.UnknownHostException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import javax.swing.JFrame;
import javax.swing.JPanel;

import Testing.PlayerCallBackImpl;
import Testing.PlayerCallBackInterface;
import Testing.PlayerMessagesInterface;

import com.sun.org.apache.bcel.internal.classfile.PMGClass;

import monsterRun.client.controller.KeyEventProcessor;
import monsterRun.client.controller.MonsterFrameMessageListener;
import monsterRun.client.model.Facade;
import monsterRun.client.model.events.IThemeChanged;
import monsterRun.client.view.popuppanels.CreateGamePanel;
import monsterRun.client.view.popuppanels.InitialLoadPanel;
import monsterRun.client.view.popuppanels.PositionPickPanel;
import monsterRun.client.view.popuppanels.RegistrationPanel;
import monsterRun.client.view.popuppanels.ScoreBoardPanel;
import monsterRun.client.view.renderer.RendererPanel;
import monsterRun.client.view.renderer.themes.AbstractBoardTheme;
import monsterRun.client.view.sidebar.GameDetailsPanel;
import monsterRun.common.model.network.NetworkMessage;
import monsterRun.common.view.Preference;

public class MonsterFrame extends JFrame implements IThemeChanged
{

	private static final long serialVersionUID = -7205566574493657595L;

	private Facade facade;

	private Toolbar toolbar;
	private JPanel container;
	private RendererPanel canvas;

	private GlassPaneManager glassPane;

	private InitialLoadPanel waitingPanel;
	private ScoreBoardPanel scorebrdPanel;
	private CreateGamePanel createGamePanel;
	private GameDetailsPanel gameDetailsPanel;
	private PositionPickPanel positionPickPanel;

	private RegistrationPanel registrationPanel;

	private KeyEventProcessor keyEventProcessor;
	private MonsterFrameMessageListener messageProcessor;
	private PlayerCallBackImpl pcbi;
	private PlayerMessagesInterface pmi;

	public MonsterFrame(int playerNum) throws UnknownHostException,
			IOException, NotBoundException
	{
		Preference.initialize(this);

		facade = new Facade(playerNum);

		// Container
		container = (JPanel) this.getContentPane();
		container.setLayout(new BorderLayout());
		container.setBackground(facade.getTheme().getInvalidCellColor());

		// Canvas
		canvas = new RendererPanel(facade);
		container.add(canvas, BorderLayout.CENTER);

		// Glass Pane
		glassPane = new GlassPaneManager((JPanel) this.getGlassPane(), canvas);

		// Toolbar
		toolbar = new Toolbar(this, facade, canvas);
		container.add(toolbar, BorderLayout.NORTH);

		// Game details panel
		gameDetailsPanel = new GameDetailsPanel(facade.getGameBoard(), canvas);
		container.add(gameDetailsPanel, BorderLayout.WEST);

		// Key Listener
		keyEventProcessor = new KeyEventProcessor(facade.getGameBoard());

		// Message processor
		messageProcessor = new MonsterFrameMessageListener(this, canvas, facade);

		// Listeners
		addWindowListener(messageProcessor);

		int playerCallBackPort = 10003 + playerNum;
		java.rmi.registry.LocateRegistry.createRegistry(playerCallBackPort);
		
		
		pcbi = new PlayerCallBackImpl(playerNum, facade, canvas, this,
				facade.getGameBoard());
		Naming.rebind("rmi://localhost:" + playerCallBackPort
				+ "/PlayerCallBackImpl", pcbi);

		
		
		pmi = (PlayerMessagesInterface) Naming
				.lookup("rmi://localhost:10002/PlayerMessagesImpl");
		
		String playerMessagesConnectionStr = "rmi://localhost:" + playerCallBackPort
				+ "/PlayerCallBackImpl";
		
		pmi.createJoinGameRequest(playerNum, playerMessagesConnectionStr);
		
		

		facade.setPcbi(pcbi);
		facade.setPmi(pmi);
		facade.themeChanged.addListener(this);
		facade.getGameBoard().setPmi(pmi);

		// facade.getCommunicator().connectionStatusChanged
		// .addListener(messageProcessor);
		// facade.getCommunicator().messageReceived.addListener(messageProcessor);
		facade.getKeyListener().moveRequested.addListener(keyEventProcessor);

		// Connect
		// facade.connectToServer();
	}

	public void close()
	{
		try
		{
			facade.disconnectFromServer();
		}
		catch (IOException e)
		{
		}

		System.exit(0);
	}

	@Override
	public void themeChanged(AbstractBoardTheme theme)
	{
		container.setBackground(theme.getInvalidCellColor());
	}

	public void hidePopups()
	{
		glassPane.removePopupComponent();
	}

	// Initial Load Panel
	public void showWaitingPanel()
	{
		if (waitingPanel == null)
		{
			waitingPanel = new InitialLoadPanel();
		}

		showPopup(waitingPanel);
		glassPane.setDrawShade(false);
	}

	// Create Game
	public void showCreateGamePanel()
	{
		if (createGamePanel == null)
		{
			createGamePanel = new CreateGamePanel(
					facade.getPlayerMessagesInterface());
			createGamePanel.setMonsterFrame(this);
		}

		showPopup(createGamePanel);
	}

	// Specify Position
	public void showPositionPanel(String senderId, NetworkMessage mess)
	{
		if (positionPickPanel == null)
		{
			positionPickPanel = new PositionPickPanel(
					facade.getPlayerMessagesInterface(), this, facade);
			// positionPickPanel.messageReceived(senderId, mess);
			try
			{
				positionPickPanel.initiatePlayerPositionSelection(facade
						.getPlayerMessagesInterface().getAvailablePositions());
			}
			catch (RemoteException e)
			{

				e.printStackTrace();
			}
		}

		showPopup(positionPickPanel);
	}

	public void showPositionPanel()
	{
		if (positionPickPanel == null)
		{
			positionPickPanel = new PositionPickPanel(
					facade.getPlayerMessagesInterface(), this, facade);
			// positionPickPanel.messageReceived(senderId, mess);
			try
			{
				positionPickPanel.initiatePlayerPositionSelection(facade
						.getPlayerMessagesInterface().getAvailablePositions());
			}
			catch (RemoteException e)
			{
				e.printStackTrace();
			}
		}

		showPopup(positionPickPanel);
	}

	// Score board Panel
	public void showScoreBoardPanel(String senderId, NetworkMessage mess)
	{

		if (scorebrdPanel == null)
		{
			scorebrdPanel = new ScoreBoardPanel(this);
			scorebrdPanel.messageReceived(senderId, mess);
		}

		showPopup(scorebrdPanel);
	}

	public void showScoreBoardPanel(int winnerId)
	{

		if (scorebrdPanel == null)
		{
			scorebrdPanel = new ScoreBoardPanel(this);
			scorebrdPanel.gameFinished(winnerId);
		}

		showPopup(scorebrdPanel);
	}

	public void showPopup(Component comp)
	{
		glassPane.setPopupComponent(comp);
		glassPane.setVisible(true);
	}

	public void joinGame() throws RemoteException
	{
		PlayerMessagesInterface pmi = facade.getPlayerMessagesInterface();
		if (pmi.isGameCreator() == true)
		{
			showCreateGamePanel();
			pmi.setCreatorStatus(false);
		}
		else
		{
			showPositionPanel();
		}
	}

	// GAreth code here

	// Registration Panel

	public void showRegistrationPanel()
	{
		if (registrationPanel == null)
		{
			registrationPanel = new RegistrationPanel(facade.getPlayerMessagesInterface());
			registrationPanel.setMonsterFrame(this);
		}

		showPopup(registrationPanel);
	}

	public void gameFinished(int playerId)
	{
		showScoreBoardPanel(playerId);
	}
}
